#ifndef CARD_H
#define CARD_H

#include <QGraphicsItem>
#include <QPainter>

class CardTexture
{
public:
    static CardTexture *instance()
    {
        if (texture == nullptr)
        {
            texture = new CardTexture();
        }
        return texture;
    }

protected:
    CardTexture()
    {
        for (int i = 0; i < 9; ++i)
        {
            large_coins[i] = QPixmap(QString(":/textures/large_icons/coins_%1.png").arg(QString::number(i + 1)));
            large_bamboo[i] = QPixmap(QString(":/textures/large_icons/bamboo_%1.png").arg(QString::number(i + 1)));
            large_characters[i] = QPixmap(QString(":/textures/large_icons/char_%1.png").arg(QString::number(i + 1)));
        }
        large_white = QPixmap(":/textures/large_icons/dragon_white.png");
        large_green = QPixmap(":/textures/large_icons/dragon_green.png");
        large_red = QPixmap(":/textures/large_icons/dragon_red.png");
        large_flower = QPixmap(":/textures/large_icons/flower.png");
        small_coins = QPixmap(":/textures/small_icons/coins.png");
        small_bamboo = QPixmap(":/textures/small_icons/bamboo.png");
        small_characters = QPixmap(":/textures/small_icons/characters.png");
        small_white = QPixmap(":/textures/small_icons/dragon_white.png");
        small_green = QPixmap(":/textures/small_icons/dragon_green.png");
        small_red = QPixmap(":/textures/small_icons/dragon_red.png");
        small_flower = QPixmap(":/textures/small_icons/flower.png");
        card_front = QPixmap(":/textures/card_front.png");
        card_back = QPixmap(":/textures/card_back.png");
        card_back_upgrade = QPixmap(":/textures/card_back_upgrade.png");
        card_shadow = QPixmap(":/textures/card_shadow.png");
        card_texture = QPixmap(":/textures/card_texture.png");
    }

public:
    QPixmap large_coins[9];
    QPixmap large_bamboo[9];
    QPixmap large_characters[9];
    QPixmap large_white;
    QPixmap large_green;
    QPixmap large_red;
    QPixmap large_flower;
    QPixmap small_coins;
    QPixmap small_bamboo;
    QPixmap small_characters;
    QPixmap small_white;
    QPixmap small_green;
    QPixmap small_red;
    QPixmap small_flower;
    QPixmap card_front;
    QPixmap card_back;
    QPixmap card_back_upgrade;
    QPixmap card_shadow;
    QPixmap card_texture;

private:
    class Deleter
    {
    public:
        ~Deleter()
        {
            if (texture != nullptr)
            {
                delete texture;
                texture = nullptr;
            }
        }
    };

private:
    static CardTexture *texture;
    static Deleter deleter;
};

enum CardType
{
    Coins, // 筒子
    Bamboo, // 条子
    Characters, // 万子
    White, // 白
    Green, // 發
    Red, // 中
    Flower // 花牌
};

class Card : public QObject, public QGraphicsItem
{
    Q_OBJECT
    Q_PROPERTY(QPointF pos READ pos WRITE setPos)

public:
    Card(CardType type, int number = 0, QGraphicsItem *parent = nullptr);

private:
    const CardTexture *texture;
    QRectF bounding_rect;
    CardType type_;
    int number_;
    enum CardState {Front, Back};
    CardState state;

public:
    QRectF boundingRect() const override;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override;
    QString str();
    CardType cardType() { return type_; }
    int cardNumber() { return number_; }
    bool isSuitedCard() { return type_ == Coins || type_ == Bamboo || type_ == Characters; }
    bool isBonusCard()  { return type_ == White || type_ == Green  || type_ == Red; }
    bool isFlowerCard() { return type_ == Flower; }
    bool isSameTypeNext(const Card *next) const
    {
        if (number_ == 0 || next->number_ == 0) return false;
        return type_ != next->type_ ? false : (number_ + 1 != next->number_ ? false : true);
    }
    bool isDifferentTypeNext(const Card *next) const
    {
        if (number_ == 0 || next->number_ == 0) return false;
        return type_ == next->type_ ? false : (number_ + 1 != next->number_ ? false : true);
    }
    void flip() { state = (state == Front ? Back : Front); update(); }
    void flipToFront() { state = Front; update(); }
    void flipToBack()  { state = Back;  update(); }

private:
    void drawCard(QPainter *painter, const QPixmap &large,
                  const QPixmap &small, const QColor color = QColor(255, 255, 255));
};

#endif // CARD_H
